package br.unifor.cct.mia.util.missingvalue;

import java.awt.Point;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

import br.unifor.cct.mia.dataenhancement.Attribute;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.GenotypeConverter;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.dataenhancement.Tuple;
import br.unifor.cct.mia.evaluate.Evaluate;
import br.unifor.cct.mia.evaluate.classification.WekaClassification;
import br.unifor.cct.mia.util.LoadFile;
import br.unifor.cct.mia.util.Methods;
import br.unifor.cct.mia.util.SaveReport;

public class MissingValueKNN {

	private static String[] datasets = {"breast","car","dermatology",
		"diabetes","iris","zoo"};

	private static int porcentagens[] = {5,10,20};
	private static int pastas[] = {1,2,3};
	
	private static Integer[] learnerTypes = {Evaluate.RBF_NETWORK };

	private static Integer[] kValues = {2,3,5};

	private static Structure st;
	private static FileWriter resultFile;

	public static void main(String[] args) throws IOException {

		DecimalFormat df = new DecimalFormat("##.##");

		for (String dbName: datasets) {

			for ( int p:pastas) {

				String path = "./Convertidas/"+dbName+"/Estratificado/20/MV"+p+"/";
				String strucFile = path+dbName+"_struc.txt";
				String testFilePath = path+dbName+"_data_test.txt";		

				Database dbTeste = LoadFile.loadDatabase(testFilePath);
				Structure st = LoadFile.loadStructure(strucFile);

				String resultFilePath = path+"RESULTADO_KNN_ERRADO_50_RBF.txt";	
				resultFile = new FileWriter(resultFilePath);

				for ( int kValue:kValues ) {

					for ( int m:porcentagens ) {
						for ( int n=1; n<=5; n++ ) {
							String dbFile = null;
							if ( m==5 )
								dbFile = path+dbName+"_data_MV-0"+m+"_"+n+".txt";
							else
								dbFile = path+dbName+"_data_MV-"+m+"_"+n+".txt";


							Date d0 = new Date();

							Database db = LoadFile.loadDatabase(dbFile);

							List positions = LoadFile.getFaultDatabase(st, db);
							Tuple tuples = new Tuple();
							db.mountStr(tuples, positions);


							String[] valoresFinal = new String[positions.size()];
							for (int i=0;i<positions.size();i++) {
								Point point = (Point)positions.get(i);

								int inicio = point.x-kValue;
								if ( inicio < 0 ) inicio = 0;

								int fim = point.x+kValue;
								if ( fim >= db.size() ) fim = db.size()-1;

								Attribute att = st.getAttribute(point.y);
								if ( att.getTipo().equalsIgnoreCase(Attribute.CONTINUOUS) ) {

									double sun = 0;
									int count = 0;				
									for(int j=inicio; j<=fim; j++) {
										String v = db.getElement(j, point.y);
										if ( v!=null && !v.equals("?") ) {
											sun += Double.parseDouble(v);
											count++;
										}
									}
									if ( att.isInteger() ) {
										valoresFinal[i] = String.valueOf( (int)(sun/count) );
									}
									else {
										valoresFinal[i] = String.valueOf( (double)((double)sun/(double)count) );
									}
								}
								else {
									List values = st.getValues(point.y);
									int[] count = new int[values.size()];

									for(int j=inicio; j<=fim; j++) {
										String v = db.getElement(j, point.y);
										if ( v!=null && !v.equals("?") ) {
											int index = values.indexOf(v);
											count[index]++;
										}
									}

									int pos = Methods.arrayMaximunPos(count);
									valoresFinal[i] = (String)values.get(pos);
								}
							}	

							try { 
								SaveReport report = new SaveReport("temp/result_mv.txt",st.getStrucFile());
								//report.addLine(tuples.string(st.getStringValues(positions, valoresFinal )));
								report.addLine(tuples.stringWithValues(positions, valoresFinal, st));
								report.saveToDisk();

								for ( Integer learnerType: learnerTypes ) {
									WekaClassification classificator = new WekaClassification(learnerType,null);
									double result = classificator.evaluate(report.getFile());

									GenotypeConverter converter = new GenotypeConverter();
									File fileTest = converter.fullConvert("temp/resultFinalTeste_MV.txt", st, dbTeste);

									classificator = new WekaClassification(learnerType,null);
									double test = classificator.evaluate(report.getFile(),fileTest);


									Date d1 = new Date();

									String line = "[k=" + kValue + "];"
									+ "[m=" + m + "];"
									+ df.format(result) + ";"
									+ df.format(test) + ";"
									+ String.valueOf((d1.getTime() - d0.getTime()) / 1000);

									System.out.println(line);
									resultFile.write(line+"\n");
									resultFile.flush();
								}
							}
							catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
				resultFile.close();
			}
		}
	}

	/*
	public static Integer J48 = new Integer(1);
	public static Integer MULTILAYER_PERCEPTRON = new Integer(2);
	public static Integer NAIVE_BAYES = new Integer(3);
	public static Integer IBK = new Integer(4);
	public static Integer PART = new Integer(5);
	 */
	private static String getEvaluateValue(int value) {

		String result = "";
		switch (value) {
		case 1:
			result = "J48";
			break;
		case 2:
			result = "MULTILAYER_PERCEPTRON";
			break;
		case 3:
			result = "NAIVE_BAYES";
			break;
		case 4:
			result = "IBK";
			break;
		case 5:
			result = "PART";
			break;
		case 6:
			result = "RBF NETWORK";
			break;
		}
		return result;
	}

}
